package wangxiaotao.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import wangxiaotao.aop.annotation.Log;
import wangxiaotao.bean.vo.OrderVO;
import wangxiaotao.common.CommonResult;
import wangxiaotao.converter.OrderConverter;
import wangxiaotao.entity.Order;
import wangxiaotao.entity.Room;
import wangxiaotao.entity.RoomType;
import wangxiaotao.enums.OrderStatue;
import wangxiaotao.enums.RoomStatue;
import wangxiaotao.tools.ConstValue;
import wangxiaotao.utils.RedisUtils;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单操作
 */
@Slf4j
@RestController
@RequestMapping("/admin/order")
@RequiredArgsConstructor
public class OrderController extends BaseController{
    private final ConstValue constValue;
    private final OrderConverter orderConverter;

    /**
     * 获取所有订单信息 包括订单用户信息
     * @return
     */
    @RequiresPermissions({"order:list"})
    @GetMapping("/list")
    @Log
    public CommonResult getAllOrder(String type, String data) {
        Page page = orderService.page(getPage(), new QueryWrapper<Order>().like(StrUtil.isNotBlank(type), type, data));
        return CommonResult.success(page);
    }

    /**
     * 管理员修改订单
     * @param orderVO
     * @return
     */
    @RequiresPermissions({"order:update"})
    @PostMapping("/update")
    @Log
    public CommonResult updateOrder(@Validated @RequestBody OrderVO orderVO) {
        //根据订单状态判断是否能修改订单数据
        orderService.judgeOrderStatue(orderVO);
        //订单修改前的房间状态
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.select("order_room_no").eq("id",orderVO.getId());
        String orderRoomNo = orderService.getObj(wrapper, s -> (String) s);
        //如果修改的房间不是原来的房间
        if (orderRoomNo!=null && !orderVO.getOrderRoomNo().equals(orderRoomNo)){
            Room room = new Room();
            room.setRoomStatue(RoomStatue.FREE)
                    .setRoomNo(orderRoomNo)
                    .setId(orderVO.getId());
            //将原来的房间的状态修改回去
            roomService.updateById(room);
            //房间类型数量修改
            RoomType roomType = roomTypeService.getById(room.getId());
            roomType.setRoomRemain(roomType.getRoomRemain()+1);
            roomTypeService.updateById(roomType);
        }else {
            //订单状态变化 修改房间状态
            roomService.changeRoomStatueByOrderStatue(orderVO.getId(),orderVO.getOrderStatue(),orderVO.getOrderRoomNo());
        }
        Order order = orderConverter.toOrder(orderVO);
        //判断订单是否为结束 -> 待评论 设置自动确认
        if (orderVO.getOrderStatue().equals(OrderStatue.WAITCOM)) {
            //设置3天后为自动付款时间
            order.setOrderAutoTime(LocalDateTime.now().plusDays(3));
            //将订单存入redis
            RedisUtils.set(orderService.getRealOrderOkPrefix(order.getOrderNo())
                    , order.getOrderNo()
                    ,orderService.getOrderOkTime());
        }
        if (orderService.updateById(order))
            return CommonResult.success();
        return CommonResult.fail();
    }

    /**
     * 管理账号添加订单
     * @param orderVO
     * @return
     */
    @RequiresPermissions({"order:add"})
    @PostMapping("/add")
    @Log
    public CommonResult addOrder(@RequestBody OrderVO orderVO) {
        //修改房间状态  锁定房间
        UpdateWrapper<Room> wrapper = new UpdateWrapper<>();
        wrapper.set("room_statue", RoomStatue.LOCK).eq("room_no",orderVO.getOrderRoomNo());
        roomService.update(wrapper);
        //默认关联用户 设置订单状态
        orderVO.setOrderStatue(OrderStatue.OKRIGHT)
                .setUserId(constValue.getDefaultOrderUserId());
        Order order = orderConverter.toOrder(orderVO);
        order.setOrderFkTime(LocalDateTime.now());
        if (orderService.save(order))
            return CommonResult.success();
        return CommonResult.fail();
    }


    /**
     * 批量操作订单  批量删除订单
     * @param orderIds
     * @return
     */
    @RequiresPermissions({"order:delete"})
    @PostMapping("/batch/delete")
    @Log
    public CommonResult batchDeleteOrder(@RequestBody Integer[] orderIds) {
        Assert.notNull(orderIds,"订单批量删除操作异常");
        if (orderService.removeBatchByIds(Arrays.asList(orderIds)))
            return CommonResult.success();
        return CommonResult.fail();
    }

    /**
     * 批量确认订单
     * @param orderIds
     * @return
     */
    @RequiresPermissions({"order:update"})
    @PostMapping("/batch/right")
    @Log
    public CommonResult batchRightOrder(@RequestBody Integer[] orderIds){
        Assert.notNull(orderIds,"订单批量确认操作异常");
        List<Order> orders = Arrays.stream(orderIds).map(s -> (Order) new Order().setOrderStatue(OrderStatue.OKRIGHT).setId(s)).collect(Collectors.toList());
        if (orderService.updateBatchById(orders))
            return CommonResult.success();
        return CommonResult.fail();
    }

    /**
     * 批量完成订单
     * @param orderIds
     */
    @RequiresPermissions({"order:update"})
    @PostMapping("/batch/ok")
    @Log
    public CommonResult batchHandleOrder(@RequestBody Integer[] orderIds) {
        Assert.notNull(orderIds,"订单批量完成操作异常");
        List<Order> orders = Arrays.stream(orderIds).map(s -> (Order) new Order().setOrderStatue(OrderStatue.OK).setId(s)).collect(Collectors.toList());
        if (orderService.updateBatchById(orders))
            return CommonResult.success();
        return CommonResult.fail();
    }

    /**
     * 在房间页面获取订单用户数据
     * @return
     */
    @GetMapping("/getUserSimpleByRoomNo/{roomNo}")
    public CommonResult getUserSimpleByRoomNo(@PathVariable String roomNo){
        QueryWrapper<Order> wrapper = new QueryWrapper<Order>()
                .select("order_name", "order_phone", "order_email")
                .eq("order_statue",OrderStatue.OKIN.getStatue())
                .eq("order_room_no", roomNo);
        return CommonResult.success(orderConverter.toOrderUserVO(orderService.getOne(wrapper)));
    }
}
